library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;


entity core_write_mux IS
  GENERIC (
            cores      : natural := 1
          );
  PORT( 
       clk                : IN std_logic;  
       
       -- sram write request
       grant              : IN std_logic;  
       grant_valid        : IN std_logic;
    
       request_out        : out std_logic;
       request_data       : out std_logic_vector(15 DOWNTO 0);
       request_addr       : out std_logic_vector(17 DOWNTO 0);
       
       -- cores request
       write_request_addr : in std_logic_vector((cores*18)-1 downto 0); 
       write_request_data : in std_logic_vector((cores*16)-1 downto 0);
       write_request_ack  : out std_logic_vector(cores-1 downto 0);
       
       start_schedule     : out  std_logic;
       schedule_nr        : in   std_logic_vector (cores-1 DOWNTO 0);
       scheduling_done    : in   std_logic           
    );
end core_write_mux;



architecture Behavioral of core_write_mux is
   
  signal addr_pointer : std_logic_vector(17 downto 0) := (others => '0');
  signal data_buffer : std_logic_vector(15 downto 0) := (others => '0');
   
  TYPE STATE_TYPE IS (
      idle,
      request,
      granted
   );
 
   SIGNAL state : STATE_TYPE := idle; 
    
begin
        

 
process (clk)
begin
  if rising_edge(clk) then
    
    
    case state is
    
      when idle =>
        if scheduling_done='1' then
          state <= request;
          addr_pointer <= write_request_addr(17 downto 0); ---- tooooooooooooodooooooooooooo for more cores
          data_buffer <= write_request_data(15 downto 0); ---- tooooooooooooodooooooooooooo for more cores
        end if; 
      
      when request =>
        if grant='1' and grant_valid='1' then
          state <= granted;
        end if;
        
      when granted =>
        if grant_valid='0' then
          state <= idle;  
        end if;
	
    end case;
    
  end if;
end process;

  request_out      <= '1' when state=request else '0';
  request_data     <= data_buffer;
  request_addr     <= addr_pointer;
  
  write_request_ack <= schedule_nr when state=request else (cores-1 downto 0 => '0');
  
  start_schedule <= '1' when state=idle and scheduling_done='1' else '0';


end Behavioral;
